<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      /*
            object.create 第一个参数绑定的原型proto上（继承绑定的对象属性方法，传入null则会没有原型链） ，第二个参数自身方法
              *第一个参数必填项，创建的值再对象原型上 proto
              *第二个参数可选  创建实例对象上的属性
              *原型上的属性修改会同步到创建的实例上
              *没有默认你的原型 指向就是第一个传入的参数，如果第一个是null则没有了
              *原型上修改后 会导致Object.create的值也发生变化
          */
      // Object.create()方法创建一个新对象，使用现有的对象来提供新创建的对象的__proto__
      const objNull = Object.create(null);
      console.log(objNull); //{}No properties

      let obj = {
        name: '你好',
        age: 18,
        fn: () => {
          console.log('执行'); //调用执行
        },
      };
      let obj2 = Object.create(obj); //obj2将继承obj的属性和方法__proto__
      console.group(obj2, obj2.name, obj2.fn()); //{} '你好' undefined

      // 增加属性
      let obj3 = Object.create(obj2, {
        name2: { value: '你好呀' },
        arr: { value: [1] },
      });
      console.log(obj3); //{name2: '你好呀'}

      let obj4 = Object.create(obj3, {
        test: {
          value: { test: '你好' }, //与属性关联的值。可以是任何有效的JavaScript值（数字，对象，函数等）默认为 undefined
          writable: true, // 标记当前属性值是否可修改， 不写默认为false，不可修改
          configurable: true, // 标识当前属性是否可以被删除，默认为false ，不可删除
          enumerable: true, //是否可枚举 默认为 false
        },
      });

      // 原型上修改值将会导致引入的值也发生变化
      obj.name = '修改你好';
      obj3.arr.push(2);
      obj4.test = {};
      console.log(obj4.name, obj4.arr); //base.html:80 修改你好 , [1, 2]
      console.log(obj4.name, obj4.arr, obj4.test, obj4); //修改你好 ,[1, 2] ,{test: {}}
    </script>
  </body>
</html>
